import {ReverseByteArrayInputStream} from "./ReverseByteArrayInputStream";
import {DataUtils} from "./DataUtils";
import {HdlcFrame} from "./sessionlayer.hdlc/HdlcFrame";
import {Apdu} from "./axdr/Apdu";
import {Choice, M698pdu} from "./axdr/M698pdu";
import {ReverseByteArrayOutputStream} from "./ReverseByteArrayOutputStream";
import {Get_Result} from "./axdr/Get_Result";
import {Data} from "./axdr/Data";
import {dataKey, FrameData} from "./bean/FrameData";


export class ParseFrame {


    parseLinkFrame(frame : string) {
        let lenPractical = frame.length - 4;//实际长度
        let len_first = frame.substring(2, 4);//帧中的数据长度前两位
        let len_second = frame.substring(4, 6);//帧中数据帧长度后两位
        let len = parseInt(len_second + len_first, 16);
        if (len * 2 != lenPractical) {
            throw new Error("帧长度不符")
        }
        // 提取链路层数据帧，获取应用层数据帧
        let appFrame;
        console.log(frame);
        let dataInputStream = new ReverseByteArrayInputStream(DataUtils.hexToBytes(frame));
        let hdlcFrame;
        try {
            hdlcFrame = new HdlcFrame().decode(dataInputStream);
            if (hdlcFrame.isSegmented()) {
                let s =  (hdlcFrame.getSegFrameType() | hdlcFrame.getSegFrameXh()).toString(16);
                while (s.length < 4) {
                    s.slice(0, 1) + "0" + s.slice(1);
                }
                appFrame = s;
            } else {
                let field = hdlcFrame.getInformationField();
                appFrame = DataUtils.toHexString(field, 1, 0);
                console.log(appFrame);
            }
        } catch (e) {
           throw new Error("frame pase error");
        }
        this.parseAppFrame(appFrame);
        // 解析应用层数据帧
        // retResult = parseAppFrame(appFrame);
        // retResult.setData(RetKey.METER698_APDU_DATA, appFrame);
        // return retResult;
    }

    parseAppFrame(frame : string){
        if(frame == null){
            throw new Error("frame is null");
        }
        let apdu;
        let m698pdu;
        console.log(DataUtils.hexToBytes(frame))
        apdu = Apdu.getInstance().decode(DataUtils.hexToBytes(frame));
        let output = new ReverseByteArrayOutputStream();
        output.setBufSize(3000);
        apdu.getCosemPdu().encode(output);
        m698pdu = new M698pdu();
        m698pdu.decode(new ReverseByteArrayInputStream(output.getArray()));
        this.parseFrame(m698pdu);
    }

    parseFrameData(m698pdu : M698pdu){
        if(m698pdu == null){
            throw new Error("frame is null");
        }
        switch (m698pdu.getChoiceIndex()){
            case Choice.GET_RESPONSE:
                if(m698pdu.get_request.getChoiceIndex()){

                }
                break;
        }
    }

    parseFrame(m698pdu : M698pdu) : String{
        let result : String = "";
        switch (m698pdu.getChoiceIndex()) {
            case Choice.GET_RESPONSE:
                result = this.parseGetResponseNormal(m698pdu.get_response.getResponseNormal.result.result);
                break;
        }
        return result;
    }

    parseGetResponseNormal(get_result : Get_Result) : String{
        let frameData = new FrameData();
        switch (get_result.getChoiceIndex()) {
            case 0:

                break;
            case 1:
                let value = this.parseData(get_result.data);
                frameData.data = value;
                break;
        }
        return JSON.stringify(frameData);
    }

    parseData(data : Data) : String{
        let map = new Map();
        let frameData;
        switch (data.getChoiceIndex()){
            case 1:
                data.array.encodeAndSave(1000);
                let list = new Array<String>();
                for(let i = 0; i < data.array.size(); i++){
                    list.push(this.parseData(data.array.get(i)));
                }
                map.set(dataKey.array, list);
                frameData = this.convertTSMapToJSObj(map);
                break;
            case 2:
                break;
            case 3:
                break;
            case 6:
                data.double_long_unsigned.encodeAndSave(1000);
                map.set(dataKey.double_long_unsigned, DataUtils.bytesToHexString(data.double_long_unsigned.dataCode, 0, data.double_long_unsigned.dataCode.length))
                frameData = this.convertTSMapToJSObj(map);
                break;
        }
        return frameData;
    }

    convertTSMapToJSObj(tsMap) {
        const jsObj = {};
        tsMap.forEach(function (value, key) {
            jsObj[key] = value;
        });
        return jsObj;
    }

}


//85010040000200010105060000000006000000000600000000060000000006000000000000

// let parse = new ParseFrame();
// parse.parseLinkFrame("682300C30511111111111100A62F850100F1000200010908510100000011335A0000C53916")

// let parse = new ParseFrame();
// parse.parseLinkFrame("682300C30511111111111100A62F850100F1000200010908510100000011335A0000C53916")

let parse = new ParseFrame();
parse.parseAppFrame("85010040000200010105060000000006000000000600000000060000000006000000000000")
